import { Input, NavBar } from "antd-mobile";
import classnames from "classnames";
import { useHistory } from "react-router-dom";
import Icon from "@/components/Icon";
import styles from "./index.module.scss";
import { useEffect, useRef, useState } from "react";
import { io, Socket } from "socket.io-client";
import { useSelector } from "react-redux";
import { RootState } from "@/types/store";

type ChatType = {
    type: "xz" | "user";
    message: string;
};

const Chat = () => {
    const history = useHistory();
    const { token } = useSelector((state: RootState) => state.login);
    const [chatList, setChatList] = useState<ChatType[]>([]);
    // 文本框的值
    const [value, setValue] = useState("");
    // 创建 ref 对象，来存储 socketio 实例，来实现多个方法中共享该变量
    const socketioRef = useRef<Socket>();
    // 创建聊天列表的 ref 对象
    const chatListRef = useRef<HTMLDivElement>(null);

    useEffect(() => {
        const socketio = io("http://toutiao.itheima.net", {
            query: {
                token,
            },
            transports: ["websocket"],
        });

        // socketio 连接成功时，就会执行此处的回调函数
        socketio.on("connect", () => {
            // console.log('socketio 链接成功')
            setChatList([
                {
                    type: "xz",
                    message: "你好，我是小智",
                },
                {
                    type: "xz",
                    message: "你有什么疑问？",
                },
            ]);
        });

        // 接收 websocket 服务器返回的消息
        socketio.on("message", (data) => {
            setChatList((chatList) => [
                ...chatList,
                {
                    type: "xz",
                    message: data.msg,
                },
            ]);
        });

        // 将 socketio 对象存储到 ref 中
        socketioRef.current = socketio;

        return () => {
            // 在组件卸载时，关闭 socket 链接
            socketio.close();
        };
    }, [token]);

    // 监听聊天内容的改变，只要聊天内容改变了，就滚动列表列表到最底部
    useEffect(() => {
        const chatListDOM = chatListRef.current;
        if (!chatListDOM) return;

        chatListDOM.scrollTop = chatListDOM.scrollHeight;
    }, [chatList]);

    // 发送消息
    const onSendMessage = (e: React.KeyboardEvent<HTMLInputElement>) => {
        // https://developer.mozilla.org/zh-CN/docs/Web/API/KeyboardEvent/code
        if (e.code === "Enter") {
            setChatList([
                ...chatList,
                {
                    type: "user",
                    message: value,
                },
            ]);
            setValue("");

            // 将消息发送给 websocket 服务器
            socketioRef.current?.emit("message", {
                msg: value,
                timestamp: Date.now() + "",
            });
        }
    };

    return (
        <div className={styles.root}>
            <NavBar className="fixed-header" onBack={() => history.go(-1)}>
                小智同学
            </NavBar>

            <div className="chat-list" ref={chatListRef}>
                {chatList.map((item, index) => (
                    <div
                        key={index}
                        className={classnames(
                            "chat-item",
                            item.type === "xz" ? "self" : "user"
                        )}>
                        {item.type === "xz" ? (
                            <Icon type="iconbtn_xiaozhitongxue" />
                        ) : (
                            <img
                                src="http://geek.itheima.net/images/user_head.jpg"
                                alt=""
                            />
                        )}
                        <div className="message">{item.message}</div>
                    </div>
                ))}
            </div>

            <div className="input-footer">
                <Input
                    className="no-border"
                    placeholder="请描述您的问题"
                    value={value}
                    onChange={(val) => setValue(val)}
                    onKeyDown={onSendMessage}
                />
                <Icon type="iconbianji" />
            </div>
        </div>
    );
};

export default Chat;
